package com.nirvana.resolve.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.read.listener.ReadListener;
import com.intellij.openapi.ui.Messages;
import com.nirvana.config.PluginConfig;
import com.nirvana.convert.CamelCaseConverter;
import com.nirvana.data.DefPropertyData;
import com.nirvana.type.ResolveState;
import org.apache.commons.lang3.StringUtils;

import java.util.*;

import static com.nirvana.resolve.ExcelResolver.MAX_HEAD_ROW;

public class HeadDataListener implements ReadListener<Map<Integer, String>> {
    private boolean hasSingleAttrColumn = false;
    private ResolveState state = ResolveState.PROPERTY_NAME;
    private final List<DefPropertyData> data = new ArrayList<>();
    private final Set<Integer> ignoreColumnSet = new HashSet<>();
    @Override
    public void invokeHead(Map<Integer, ReadCellData<?>> headMap, AnalysisContext context) {
        ReadListener.super.invokeHead(headMap, context);
        switch (state) {
            case PROPERTY_NAME -> {
                state = ResolveState.COMMENT;
                int size = headMap.size();
                for (int i = 0; i < size; i++) {
                    ReadCellData<?> readCellData = headMap.getOrDefault(i, null);
                    if (readCellData == null) {
                        ignoreColumnSet.add(i);
                        continue;
                    }
                    String name = readCellData.getStringValue();
                    if (StringUtils.isBlank(name)
                            || name.startsWith("#")
                            || PluginConfig.getInstance().checkIgnoreField(name)) {
                        ignoreColumnSet.add(i);
                        if (PluginConfig.getInstance().isAttrName(name)) hasSingleAttrColumn = true;
                    } else {
                        DefPropertyData defPropertyData = new DefPropertyData();
                        defPropertyData.setPropertyName(CamelCaseConverter.toCamelCase(name, true));
                        defPropertyData.setSourceName(name);
                        data.add(defPropertyData);
                    }
                }
            }
            case COMMENT -> {
                state = ResolveState.TYPE;
                int size = headMap.size();
                int index = 0;
                for (int i = 0; i < size; i++) {
                    if (ignoreColumnSet.contains(i)) continue;
                    ReadCellData<?> readCellData = headMap.get(i);
                    String comment = readCellData.getStringValue();
                    if (index < data.size()) {
                        data.get(index++).setComment(comment);
                    }
                }
            }
            case TYPE -> {
                state = ResolveState.NONE;
                int size = headMap.size();
                int index = 0;
                for (int i = 0; i < size; i++) {
                    if (ignoreColumnSet.contains(i)) continue;
                    ReadCellData<?> readCellData = headMap.get(i);
                    String type = readCellData.getStringValue();
                    if (index < data.size()) {
                        data.get(index++).setTypeIndex(type.replace(":", ""));
                    }
                }
            }
            default -> {

            }
        }
    }

    @Override
    public void invoke(Map<Integer, String> data, AnalysisContext context) {

    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
    }

    @Override
    public boolean hasNext(AnalysisContext context) {
        return context.readRowHolder().getRowIndex() < MAX_HEAD_ROW - 1;
    }

    public List<DefPropertyData> getData() {
        if (hasSingleAttrColumn) {
            Messages.showWarningDialog("存在单独的属性列，请考虑新增字段attr: BaseAttr封装这些属性", "建议信息");
        }
        return data;
    }
}
